#ifndef K_DEBUG_SERVER_H
#define K_DEBUG_SERVER_H
#pragma once

#include "KNetScene.h"
#include "KStreamAction.h"
#include <cstdint>
#include <set>
#include <string>

class KDebugServer;

class KDebugActionPasv : public KStreamAction {
private:
    explicit KDebugActionPasv(KPageList *pool = NULL);
    friend class KDebugServer;
protected:
    KDebugServer *server() const;
protected:
    bool sendPackage(const KPackage &pack);
protected:
    virtual void abortImp();
    virtual void onError(KDef::SockError type, DWORD error);
    virtual void onReceived(KKey *&key, void *data, size_t length, bool more);
};

class KDebugServer : public KNetItem, protected KLockable {
public:
    explicit KDebugServer(KPageList *pool = NULL, u_short port = 0);
public:
    void setAttr(uint32_t backColor, uint32_t foreColor);
    void setInfo(const std::string &info, bool title = false);
    u_short portUsed() const    { return m_port_used; }
    void setPort(u_short port)  { m_port = port; }
protected:
    virtual int filter() const
    {
        return KNetItem::FilterAccepted
            | KNetItem::FilterError
            | KNetItem::FilterReceived
            | KNetItem::FilterSent;
    }
protected:
    virtual void onStarted();
    virtual void onStopped();
    virtual void onAccepted(KSocket *sock, KKey *key);
private:
    void removeClient(KDebugActionPasv *client);
    void sendToClients(const KPackage &pack);
private:
    KPageList *const m_pool;
    std::set<KDebugActionPasv *> m_clients;
    u_short m_port, m_port_used;
    friend class KDebugActionPasv;
};

#endif // K_DEBUG_SERVER_H